/*-*-C-*-
 *
 * Types and functions for talking to the Wimp
 */

#ifndef __defined_wimp_h
#define __defined_wimp_h


#ifndef Wimp_TextOp
#define Wimp_TextOp (0x400f9)
#endif


typedef struct
{
        int minx, miny, maxx, maxy;
} RectRec, *RectPtr;

typedef struct
{
        int x, y;
} PointRec, *PointPtr;

typedef struct
{
        unsigned char titleFG,
                      titleBG,
                      workFG,
                      workBG,
                      scrollBG,         /* outer */
                      scrollFG,         /* inner */
                      focusBG,          /* title */
                      reserved;         /* == zero */
} WindowColoursRec, *WindowColoursPtr;

typedef struct
{
        unsigned short width, height;
} ShortSizeRec, *ShortSizePtr;

typedef struct
{
        RectRec bbox;
        unsigned int flags;
        unsigned int data[3];
} IconRec, *IconPtr;

typedef struct
{
        int windowhandle;
        IconRec icon;
} CreateIconRec, *CreateIconPtr;

typedef struct
{
        int windowhandle;
        int iconhandle;
        IconRec icon;
} IconStateRec, *IconStatePtr;

typedef struct
{
        int windowhandle;
        int iconhandle;
        unsigned int eor;
        unsigned int clear;
} SetIconStateRec, *SetIconStatePtr;


/*
 * NOTE!
 * The memory blocks required by Wimp_CreateWindow and Wimp_LoadTemplate
 * start at visarea, not handle.  For convenience in using the other calls,
 * I have decided not to use a substructure, but to simply add in the
 * offset when doing the calls that need it.
 */

typedef struct
{
        int handle;
        RectRec visarea;
        PointRec scrolloffset;
        int behind;
        unsigned int flags;
        WindowColoursRec colours;
        RectRec workarea;
        unsigned int titleflags;
        unsigned int workareaflags;
        void *spritearea;
        ShortSizeRec minsize;
        int titledata[3];
        unsigned int numicons;

        IconRec icons[1];               /* sic */
} WindowRec, *WindowPtr;


typedef struct
{
    int handle;
    RectRec visarea;
    PointRec scrolloffset;
    RectRec graphwin;
} WindowRedrawRec, *WindowRedrawPtr;


typedef struct
{
    int handle;
    RectRec visarea;
    PointRec scrolloffset;
    int behind;
    unsigned int flags;
} WindowStateRec, *WindowStatePtr;


typedef struct
{
    int handle;
    RectRec bbox;
} WindowOutlineRec, *WindowOutlinePtr;


typedef struct
{
    PointRec position;
    int buttons;
    int windowhandle;
    int iconhandle;
} MouseClickRec, *MouseClickPtr;


typedef struct
{
    int windowhandle;
    int type;
    RectRec initial;
    RectRec constrain;
    unsigned int R12, draw, remove, move;
} DragBoxRec, *DragBoxPtr;

typedef struct
{
    int windowhandle;
    int iconhandle;
    PointRec position;
    int height;
    int index;
} CaretPositionRec, *CaretPositionPtr;

typedef struct
{
    CaretPositionRec caret;
    unsigned int code;
} KeyPressRec, *KeyPressPtr;
    
typedef struct
{
    PointRec position;
    int buttons;
    int windowhandle;
    int iconhandle;
} PointerInfoRec, *PointerInfoPtr;

typedef struct
{
    int size;
    int sender;
    int myref;
    int yourref;
    int code;
    int data[1];                /* sic */
} MessageRec, *MessagePtr;

typedef struct
{
    unsigned int flags;
    char *title;
    int x;
    unsigned int reserved1;
    unsigned int reserved2;
    int y;
    unsigned int reserved3;
    unsigned int reserved4;
    unsigned int rgb;
    char extensionsize;
} ColourPickerBlockRec, *ColourPickerBlockPtr;


#define BIT(n) (((unsigned int) 1) << (n))
#define MASK(n) ((unsigned int)((BIT((n))) - 1))

/*
 * Window flags
 */

/* Old-style gadget flags */
#define WF_OLD_TITLE                    BIT(0)
#define WF_OLD_VSCROLL                  BIT(2)
#define WF_OLD_HSCROLL                  BIT(3)
#define WF_OLD_NO_CLOSE                 BIT(7)

#define WF_MOVEABLE                     BIT(1)
#define WF_AUTO_REDRAW                  BIT(4)
#define WF_PANE                         BIT(5)
#define WF_ALLOW_OFF                    BIT(6)
#define WF_USER_SCROLL                  BIT(8)
#define WF_NO_REPEAT                    BIT(9)
#define WF_GCOL                         BIT(10)
#define WF_BACKDROP                     BIT(11)
#define WF_HOTKEYS                      BIT(12)
#define WF_KEEP_ON                      BIT(13)
#define WF_FREE_RIGHT                   BIT(14)
#define WF_FREE_BOTTOM                  BIT(15)

/* Read only (Wimp_GetWindowState) */
#define WF_INFO_OPEN                    BIT(16)
#define WF_INFO_FULLY_VISIBLE           BIT(17)
#define WF_INFO_FULL_SIZE               BIT(18)
#define WF_INFO_TOGGLING_SIZE           BIT(19)
#define WF_INFO_INPUT_FOCUS             BIT(20)
#define WF_INFO_FORCE_ON                BIT(21)

/* Should be 0 */
#define WF_RESERVED22                   BIT(22)
#define WF_RESERVED23                   BIT(23)

/* New-style gadget flags */
#define WF_BACK                         BIT(24)
#define WF_CLOSE                        BIT(25)
#define WF_TITLE                        BIT(26)
#define WF_TOGGLE                       BIT(27)
#define WF_VSCROLL                      BIT(28)
#define WF_RESIZE                       BIT(29)
#define WF_HSCROLL                      BIT(30)

/* 1 for new, 0 for old style gadget flags */
#define WF_NEWSTYLE                     BIT(31)

/* Useful groups */

#define WF_OLD_GADGETS (WF_OLD_TITLE | WF_OLD_VSCROLL | WF_OLD_HSCROLL | WF_OLD_NO_CLOSE)
#define WF_NEW_GADGETS (WF_BACK | WF_CLOSE | WF_TITLE | WF_TOGGLE | WF_VSCROLL | WF_RESIZE | WF_HSCROLL)
#define WF_INFO_ONLY (WF_INFO_OPEN | WF_INFO_FULLY_VISIBLE | WF_INFO_FULL_SIZE | WF_INFO_TOGGLING_SIZE | WF_INFO_INPUT_FOCUS | WF_INFO_FORCE_ON)
#define WF_RESERVED (WF_RESERVED22 | WF_RESERVED23)


/*
 * Icon flags
 */

#define IF_TEXT                         BIT(0)
#define IF_SPRITE                       BIT(1)
#define IF_BORDER                       BIT(2)
#define IF_HCENT                        BIT(3)
#define IF_VCENT                        BIT(4)
#define IF_FILLED                       BIT(5)
#define IF_FONT                         BIT(6)
#define IF_HELP                         BIT(7)
#define IF_INDIR                        BIT(8)
#define IF_RJUST                        BIT(9)
#define IF_ADJUST                       BIT(10)
#define IF_HALFSIZE                     BIT(11)

#define IF_SELECTED                     BIT(21)
#define IF_SHADED                       BIT(22)
#define IF_DELETED                      BIT(23)

/* Numeric fields */
#define IF_TYPE_MASK                    MASK(4)
#define IF_TYPE_SHFT                    (12)

#define IF_ESG_MASK                     MASK(5)
#define IF_ESG_SHFT                     (16)

/* if IF_FONT clear */
#define IF_FG_MASK                      MASK(4)
#define IF_FG_SHFT                      (24)
#define IF_BG_MASK                      MASK(4)
#define IF_BG_SHFT                      (28)

/* if IF_FONT set */
#define IF_FONT_MASK                    MASK(8)
#define IF_FONT_SHFT                    (24)

/* Useful groups */
#define IF_IST                          (IF_INDIR | IF_SPRITE | IF_TEXT)
#define IF_FIELD(f,n) (((n) & IF_##f##_MASK) << IF_##f##_SHFT)
#define IF_GET_FIELD(f,n) (((n) >> IF_##f##_SHFT) & IF_##f##_MASK)
#define IF_SET_FIELD(f,n,v) ((n) = (((n) & ~(IF_##f##_MASK << IF_##f##_SHFT)) | (IF_FIELD(f,v))))


/*
 * Mouse button values
 */

#define MB_SELECT                       BIT(2)
#define MB_MENU                         BIT(1)
#define MB_ADJUST                       BIT(0)

/* The following multipliers only valid for Click/Drag/Double icons */

#define MB_SINGLECLICK(n)               (256 * (n))
#define MB_DRAG(n)                      (16 * (n))
#define MB_DOUBLE(n)                    (1 * (n))

/* The following is for others */

#define MB_CLICK(n)                     (1 * (n))


/*
 * Wimp_Poll events
 */

#define EV_NULL_REASON_CODE             (0)
#define EV_REDRAW_WINDOW_REQUEST        (1)
#define EV_OPEN_WINDOW_REQUEST          (2)
#define EV_CLOSE_WINDOW_REQUEST         (3)
#define EV_POINTER_LEAVING_WINDOW       (4)
#define EV_POINTER_ENTERING_WINDOW      (5)
#define EV_MOUSE_CLICK                  (6)
#define EV_USER_DRAG_BOX                (7)
#define EV_KEY_PRESSED                  (8)
#define EV_MENU_SELECTION               (9)
#define EV_SCROLL_REQUEST               (10)
#define EV_LOSE_CARET                   (11)
#define EV_GAIN_CARET                   (12)
#define EV_USER_MESSAGE                 (17)
#define EV_USER_MESSAGE_RECORDED        (18)
#define EV_USER_MESSAGE_ACKNOWLEDGE     (19)

/*
 * To generate event masks for Wimp_Poll, use BIT with the above
 * values.  AND with the following value for safety:-
 */

#define EF_VALID 0xE1973

typedef enum
{
    ScreenToWork = -1,
    WorkToScreen = 1
} ConvertType;


#define KEYCODE_SHIFT 0
#define KEYCODE_CTRL 1
#define KEYCODE_ALT 2
#define MODIFIER_SHIFT BIT(0)
#define MODIFIER_CTRL BIT(1)
#define MODIFIER_ALT BIT(2)


extern int scalex, scaley;        /* pixel-to-OSunit conversion factors */
extern int screenx, screeny;      /* screen size in OS units */

extern error * wimp_examine_mode (void);
extern error * wimp_load_template (char *name, WindowPtr *windowret);
extern error * wimp_load_template_returning_size (char *name, WindowPtr *windowret, int *size);
extern error * wimp_copy_template (WindowPtr pattern, WindowPtr *ret, int size);
extern int wimp_point_inside (RectPtr rect, PointPtr point);
extern int wimp_rects_intersect(RectPtr one, RectPtr two);
extern int wimp_rect_contained (RectPtr small, RectPtr large);
extern void wimp_convert_point (ConvertType type, WindowPtr win, PointPtr in, PointPtr out);
extern void wimp_convert_rect (ConvertType type, WindowPtr win, RectPtr in, RectPtr out);
extern void wimp_regularise_rect (RectPtr rect);
extern void wimp_merge_bboxes (RectPtr out, RectPtr one, RectPtr two);
extern Bool wimp_bboxes_different (RectPtr one, RectPtr two);
extern unsigned int wimp_read_modifiers (void);
extern error * wimp_invalidate (WindowPtr win, RectPtr area);
extern error * wimp_move_caret (WindowPtr window, int i);
extern void wimp_move_window (WindowPtr win, int x, int y);
extern Bool wimp_read_icon_name (int w, int i, char *buf);
extern error * wimp_set_dotdash (char *eight);
extern void wimp_cycle_pattern (void);
extern void wimp_plot_eor_box (WindowPtr win, RectPtr work);
extern void wimp_update_eor_box (WindowPtr win, RectPtr work);
extern void wimp_start_rotate_box (void);
extern void wimp_end_rotate_box (void);
extern int wimp_string_width (char *string);

extern void wimp_align_rect (RectPtr box);
extern void wimp_align_point (PointPtr point);

extern void wimp_read_window_constraints (Bool *topleft, Bool *bottomright);


#define WIMP_ALIGN_COORD(x) (((x)+2) & ~3)

#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))


/*
 * Messages
 */


typedef struct
{
    int size;
    int taskhandle;
    int myref;
    int yourref;
    int messageid;
} MessageHeaderRec, *MessageHeaderPtr;

#define MESSAGE_QUIT (0)
#define MESSAGE_PREQUIT (8)

typedef struct
{
    MessageHeaderRec header;
    unsigned int flags;         /* only if header.size permits */
} MessagePreQuitRec, *MessagePreQuitPtr;


#define MESSAGE_PALETTECHANGE (9)

#define MESSAGE_DRAGGING (17)

typedef struct
{
    MessageHeaderRec header;
    int windowhandle, iconhandle;
    PointRec position;
    unsigned int flags;
    RectRec bbox;
    int filetypes[1];           /* sic */
} MessageDraggingRec, *MessageDraggingPtr;


#define MESSAGE_DRAG_CLAIM (18)

typedef struct
{
    MessageHeaderRec header;
    unsigned int flags;
    int filetypes[1];           /* sic */
} MessageDragClaimRec, *MessageDragClaimPtr;


#define MESSAGE_DATA_SAVE (1)
#define MESSAGE_DATA_SAVE_ACK (2)

typedef struct
{
    MessageHeaderRec header;
    int windowhandle, iconhandle;
    PointRec position;          /* screen relative */
    int estsize;
    int filetype;
    char leafname[256 - sizeof(MessageHeaderRec) - 6 * sizeof(int)];
} MessageDataSaveRec, *MessageDataSavePtr;


#define MESSAGE_DATA_LOAD (3)
#define MESSAGE_DATA_LOAD_ACK (4)  /* use MessageDataLoadRec */
#define MESSAGE_DATA_OPEN (5)      /* use MessageDataLoadRec */

typedef struct
{
    MessageHeaderRec header;
    int windowhandle, iconhandle;
    PointRec position;          /* screen relative */
    int estsize;
    int filetype;
    char filename[256 - sizeof(MessageHeaderRec) - 6 * sizeof(int)];
} MessageDataLoadRec, *MessageDataLoadPtr;


#define MESSAGE_RAM_FETCH (6)
typedef struct
{
    MessageHeaderRec header;
    unsigned int buffer;
    unsigned int buflen;
} MessageRamFetchRec, *MessageRamFetchPtr;


#define MESSAGE_RAM_TRANSMIT (7)
typedef struct
{
    MessageHeaderRec header;
    unsigned int buffer;
    unsigned int numsent;
} MessageRamTransmitRec, *MessageRamTransmitPtr;


#define MESSAGE_FILER_OPEN_DIR (0x400)

typedef struct
{
    MessageHeaderRec header;
    int fsnumber;
    int flags;      /* 1 => do not canonicalise name */
    char filename[256 - sizeof(MessageHeaderRec) - 2 * sizeof(int)];
} MessageFilerOpenDirRec, *MessageFilerOpenDirPtr;


#define MESSAGE_HELP_REQUEST (0x502)

typedef struct
{
    MessageHeaderRec header;
    PointerInfoRec mouse;
} MessageHelpRequestRec, *MessageHelpRequestPtr;


#define MESSAGE_HELP_REPLY (0x503)

typedef struct
{
    MessageHeaderRec header;
    char help[200];
} MessageHelpReplyRec, *MessageHelpReplyPtr;

#define MESSAGE_MODE_CHANGE (0x400c1)


#define MESSAGE_MENU_WARNING (0x400C0)

typedef struct
{
    MessageHeaderRec header;
    void (*submenu) (void);    /* more convenient as a dummy function type */
    PointRec position;
    int choice[256/4 - 5 - 2];
} MessageMenuWarningRec, *MessageMenuWarningPtr;


#define MESSAGE_SAVE_DESKTOP (0xA)

typedef struct
{
    MessageHeaderRec header;
    int filehandle;
    unsigned int flags;
} MessageSaveDesktopRec, *MessageSaveDesktopPtr;


#define MESSAGE_TASK_CLOSE_DOWN (0x400c3)

typedef struct
{
    MessageHeaderRec header;
} MessageTaskCloseDownRec, *MessageTaskCloseDownPtr;


#define MESSAGE_MENUS_DELETED (0x400c9)

typedef struct
{
    MessageHeaderRec header;
    void *menu;
} MessageMenusDeletedRec, *MessageMenusDeletedPtr;


#define MESSAGE_CLAIM_ENTITY (15)

typedef struct
{
    MessageHeaderRec header;
    unsigned int flags;
} MessageClaimEntityRec, *MessageClaimEntityPtr;


#define MESSAGE_FONT_CHANGED (0x400cf)

typedef struct
{
    MessageHeaderRec header;
    unsigned int fonthandle;
} MessageFontChangedRec, *MessageFontChangedPtr;


#define MESSAGE_COLOUR_PICKER_COLOUR_CHOICE (0x47700)

typedef struct
{
    MessageHeaderRec header;
    int handle;
    unsigned int flags;
    unsigned int rgb;
} MessageColourPickerColourChoiceRec, *MessageColourPickerColourChoicePtr;


#endif
